/**
 *  \file   button.c
 *  \author Miora ANDRIAMANOHARISOA, Loic MINGHETTI
 *  \date   PFE 2011
 **/
 


#include "include.h"
#include <stdlib.h>


// verbocity
int verbocity = 0;


#define ANTIBOUNCING_DURATION 10
static int button_antibouncing_flag;
static int button_pressed_flag;



void button_antibouncing_elapsed() {
	if (verbocity >= 2) printf("Button antiboucing elapsed");
	button_antibouncing_flag = 0;
	timer_unwatch(&TIMER_ANTIBOUNCING);
}


void button_pressed_cb() {
    if(button_antibouncing_flag == 0)
    {
        button_pressed_flag = 1;
        button_antibouncing_flag = 1;
        
        TIMER_ANTIBOUNCING = 0;
        timer_watch(&TIMER_ANTIBOUNCING, button_antibouncing_elapsed, 3);
    }
}


#define UART_MAX_CHARS 10

static char uart_data[UART_MAX_CHARS];

#define UART_READ_IDLE 0
#define UART_READ_INT 1
#define UART_EXIT_PRESSED 2
#define UART_ENTER_PRESSED 3
static int uart_state = UART_READ_IDLE;
static int uart_read_pos = -1;


// called on key press (process ESC, ENTER, Backspace, and digits 
int uart_cb(uint8_t data) {
	if (uart_state == UART_READ_INT) {
		switch (data) {
			case 0x1B : uart_state = UART_EXIT_PRESSED; break;
			case 0x8 : 
				if (uart_read_pos > -1) {
					// backspace (replace last char by a space)
					printf("%c %c", 0x8, 0x8);
					uart_read_pos--;
				}
				break;
			case 0xA : 
			case 0xB : 
			case 0xC : 
			case 0xD : uart_state = UART_ENTER_PRESSED; break;
			default :
				if (uart_read_pos+2 < UART_MAX_CHARS && data >= 0x30 && data <= 0x39) {
					printf("%c", (unsigned char) data);
					uart_data[++uart_read_pos] = (unsigned char) data;
				}
				break;
		}
	}
	return 0;
}

// get last stored int typed in
static unsigned int uart_get_int() {
	uart_data[++uart_read_pos] = '\0';
	return atoi(uart_data);
}

static void uart_reset () {
	uart_read_pos = -1;
	uart_state = UART_READ_IDLE;
}

static void print_header() {
	int current = sensor_get_real_temp();
	int avg = sensor_get_real_temp_avg();
	
printf("%c\
+-------------------------------------------------------------------+\r\n\
|      CoolSens Temperature Monitoring Wireless Sensor Network      |\r\n\
|                        - Node configuration -                     |\r\n\
+-------------------------------------------------------------------+\r\n\
\n\n\
Node ID : %u\r\n\
Current temperature : %d.%d %cC\r\n\
Average temperature : %d.%d %cC\r\n\
Node hop count to sink : %d\r\n\
\n", 0x0c, node_id, current/10, (current < 0)? -1*current%10 : current%10, 0xA7, avg/10, (avg < 0)? -1*avg%10 : avg%10, 0xA7, node_hop_count);

}




PT_THREAD(thread_ui(struct pt *pt))
{
	static unsigned int menu;
	unsigned int new_id;
	static temp_data data;
	
   PT_BEGIN(pt);

 	button_pressed_flag = 0;
	uart_reset();
	uart_state = UART_READ_INT;
	

	// if node is sink, go directly to menu #3
	if (node_id > 0) {
		print_header();
		printf ("1. Change node ID\r\n2. Calibrate sensor\r\n3. Set node as sink\r\n4. Transmit dummy packet\r\n5. Make verbose\r\n6. Exit\r\n");
		printf ("\n\nSelect your choice and hit enter : ");
		
		// wait for choice 
		PT_WAIT_UNTIL(pt, uart_state == UART_ENTER_PRESSED || uart_state == UART_EXIT_PRESSED || button_pressed_flag);
		if (button_pressed_flag || uart_state == UART_EXIT_PRESSED) PT_RESTART(pt);
		menu = uart_get_int();
		
	} else {
		menu = 3;
	}
	
	// change ID 
	if (menu == 1) {
		print_header();
		printf ("\n\nNew ID must be unique and between 1 and 65535. \r\nTo cancel, press ESC.\r\n\nType new ID and hit enter : ");
		uart_reset();
		uart_state = UART_READ_INT;
		
		PT_WAIT_UNTIL(pt, uart_state == UART_ENTER_PRESSED || uart_state == UART_EXIT_PRESSED || button_pressed_flag);
		if (button_pressed_flag || uart_state == UART_EXIT_PRESSED) PT_RESTART(pt);
		new_id = uart_get_int();
		if (new_id > 65535 || new_id < 1) {
			printf ("\r\n\nInvalid ID. Press enter to continue.");
		} else {
			node_id = new_id;
			flash_save_config();
			printf ("\r\n\nNew ID is %u. Press enter to continue.", node_id);
		}
		uart_reset();
		uart_state = UART_READ_INT;
		
		PT_WAIT_UNTIL(pt, uart_state == UART_ENTER_PRESSED || uart_state == UART_EXIT_PRESSED || button_pressed_flag);
		PT_RESTART(pt);
	
	// calibrate sensor 
	} else if (menu == 2) {
		print_header();
		printf ("\n\nTo calibrate sensor, set current room temperature in tenths of degree celsius (eg. 225 for 22.5 deg).\r\nTo cancel, press ESC.\r\n\nType temperature and hit enter : ");
		uart_reset();
		uart_state = UART_READ_INT;
		
		PT_WAIT_UNTIL(pt, uart_state == UART_ENTER_PRESSED || uart_state == UART_EXIT_PRESSED || button_pressed_flag);
		if (button_pressed_flag || uart_state == UART_EXIT_PRESSED) PT_RESTART(pt);
		printf ("\r\n\nNew temperature is %d. Press enter to continue.", uart_get_int());
		sensor_set_real_temp(uart_get_int());
		uart_reset();
		uart_state = UART_READ_INT;
		
		PT_WAIT_UNTIL(pt, uart_state == UART_ENTER_PRESSED || uart_state == UART_EXIT_PRESSED || button_pressed_flag);
		PT_RESTART(pt);
	
	// make verbose 
	} else if (menu == 5) {
		print_header();
		printf ("\n\nHit exit to return to previous screen when done.\r\n");
		uart_reset();
		uart_state = UART_READ_INT;
		verbocity = CONF_VERBOCITY_LEVEL;

		PT_WAIT_UNTIL(pt, uart_state == UART_ENTER_PRESSED || uart_state == UART_EXIT_PRESSED || button_pressed_flag);
		verbocity = 0;
		PT_RESTART(pt);

	// make sink (and verbose - tmp)
	} else if (menu == 3) {
		if (node_id != 0) {
			node_id = 0;
			flash_save_config();
		}
		node_hop_count = 0;
		verbocity = 3; // tmp
		
		PT_WAIT_UNTIL(pt, uart_state == UART_EXIT_PRESSED || button_pressed_flag);
		node_id = -1;
		node_hop_count = 1;
		verbocity = 0; // tmp
		PT_RESTART(pt);
		
	// force sending of a dummy packet
	} else if (menu == 4) {
		print_header();
		printf ("\n\nEnter temperature in tenths of degree celsius (eg. 225 for 22.5 deg) that you want to send.\r\nTo cancel, press ESC.\r\n\nType temperature and hit enter : ");
		uart_reset();
		uart_state = UART_READ_INT;
		
		PT_WAIT_UNTIL(pt, uart_state == UART_ENTER_PRESSED || uart_state == UART_EXIT_PRESSED || button_pressed_flag);
		if (button_pressed_flag || uart_state == UART_EXIT_PRESSED) PT_RESTART(pt);
		
	    data.source = node_id;
	    sensor_data_counter++;
	    flash_save_config();
	    data.packet_number = sensor_data_counter;
	    data.temp = uart_get_int();
	    PT_WAIT_UNTIL(pt, xmac_tx_append(data) == 0); // wait until msg has been appended
	    if (verbocity) printf("\r\nNew message generated");
	    
		printf ("\r\n\nSent temperature is %d. Press enter to continue.", uart_get_int());
		uart_reset();
		uart_state = UART_READ_INT;
		
		PT_WAIT_UNTIL(pt, uart_state == UART_ENTER_PRESSED || uart_state == UART_EXIT_PRESSED || button_pressed_flag);
		PT_RESTART(pt);


		
	} else {
		PT_RESTART(pt);
	}
		
   PT_END(pt);
}



void ui_init() {

    /* button init */
    button_init();
    button_register_cb(button_pressed_cb);
    
    button_antibouncing_flag = 0;
    button_pressed_flag = 0;

    button_enable_interrupt();
    
    /* UART init (serial link) */
    uart_init(UART_9600_SMCLK_8MHZ);
    uart_register_cb(uart_cb);
    uart_data[0] = '\n';
	uart_state = UART_READ_IDLE;
	uart_read_pos = -1;
    
}
